package dao;

import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import beans.*;
import db.DBDruidManager;
import net.sf.json.JSONObject;
import utils.Log4jInit;
@Component
public class AlgorithmDao implements Serializable {
	@Autowired
	CompanyDao companyDao;
	private String name;

	public AlgorithmDao() {
	}

	public AlgorithmDao(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	private static final long serialVersionUID = -3009298837409577024L;

	/**
	 * get algorithm name by algorithm id
	 * by zhuyaokun
	 * @param algorithmId
	 * @return
	 */
	public String getAlgorithmNameById(String algorithmId){
		String sql = "select name from algorithm where id = ?";
		return (String) Query.executeQueryObject(sql, new Object[]{algorithmId}, new QueryCallBack() {
			
			@Override
			public Object doExecute(ResultSet rs) {
				String result = "";
				try {
					while(rs.next())
						result = rs.getString("name");
				} catch (SQLException e) {
					e.printStackTrace();
				}
				return result;
			}
		});
	}

	private AlgorithmDetail packAlgorithm(AlgorithmDetail a,ResultSet rs, Map<String,Category> categoryMap ) throws SQLException {
		a.setName(rs.getString("name"));
		a.setIntroduction(rs.getString("introduction"));
		a.setInputCount(rs.getInt("input_count"));
		a.setOutputCount(rs.getInt("output_count"));
		a.setParamsCount(rs.getInt("params_count"));
		a.setVersion(rs.getString("version"));
		a.setFunction(categoryMap.get("function"));
		a.setLocationUri(rs.getString("location_uri"));
		a.setCompanyName(rs.getString("company_name"));
		a.setPostfix(rs.getString("postfix"));
		a.setPlatform(rs.getString("platform"));
		a.setContainGpu(rs.getBoolean("is_contain_gpu"));
		a.setUseMpi(rs.getBoolean("is_use_mpi"));
		a.setMinCpuIdle(rs.getFloat("min_cpu_idle"));
		a.setMinRamRemaining(rs.getFloat("min_ram_remaining"));
		a.setId(rs.getInt("id"));
		a.setDelete(rs.getBoolean("is_delete"));
		a.setType(categoryMap.get("type"));
		a.setGenetic(rs.getBoolean("is_genetic"));
        a.setCpuNum(String.valueOf(rs.getInt("cpu_num")));
   //     System.out.println("cpu_num::"+a.getCpuNum());
		return a;
	}

	public List<Object> getAlgorithms(String userId, Integer onePageCount, Integer currentPage) {
		String sql = "select * from algorithm where is_delete = 0 order by id desc limit "
				+ (currentPage - 1) * onePageCount + " , " + onePageCount;
		List<Object> algorithms = new ArrayList<>();
		algorithms = Query.executeQueryList(algorithms, sql, null, new QueryCallBackList() {
			@Override
			public List<Object> doExecuteList(ResultSet rs, List<Object> results) {
				try {
					while (rs.next()) {
						final Map<String,Category> categoryMap = new AlgorithmDao().categoryDetail(rs.getInt("id")+"");
						AlgorithmDetail a = new AlgorithmDetail();
						if (categoryMap!=null) {
							a = packAlgorithm(a,rs,categoryMap);
							a.setCompanyJson((JSONObject) companyDao.showOneCompany(a.getCompanyName()).get(0));
							if (!rs.getBoolean("is_delete"))
								results.add(a);
						}
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}finally{
//	               	 DBDruidManager.closeConnection();
	               }
				return results;
			}
		});
		return algorithms;
	}

	/**
	 * 根据每页数量计算总页数 By朱耀堃
	 *
	 * @param onePageCount
	 * @return
	 */
	public int getAlgorithmPageNumInCategory(Integer onePageCount) {
		int algorithmNum = this.getAlgorithmNumInCategory();
		return (algorithmNum % onePageCount) == 0 ? (algorithmNum / onePageCount) : (algorithmNum / onePageCount + 1);
	}

	/**
	 * 获取所有的算法数量
	 *
	 * @return
	 */
	public synchronized int getAlgorithmNum() {
		String sql = "select count(*) from algorithm where is_delete = 0";
		return PublicDao.oneNum(sql,null);
	}

	public synchronized int getAlgorithmNumInCategory() {
		String sql = "select count(*) from algorithm,category where `algorithm`.is_delete = 0 " +
				"and `algorithm`.function = category.categoryId union select count(*) from " +
				"algorithm,category where `algorithm`.is_delete = 0 and `algorithm`.type = category.categoryId";
		return PublicDao.oneNum(sql,null);
	}
	/**
	 * Byzhuyaokun 获取指定算法细节
	 */
	public AlgorithmDetail getAlgorithmDetailWithoutUserId(String algorithmId) {
		if(algorithmId==null)
			return null;
		AlgorithmDetail algorithmDetail = new AlgorithmDetail();

		String inputSql = "select * from algorithm_input where algorithm_id=?";
		final List<AlgorithmInput> algorithmInputs = new ArrayList<>();
		int inputNum = packInputDetail(inputSql,algorithmId,algorithmInputs);

		String outputSql = "select * from algorithm_output where algorithm_id=?";
		final List<AlgorithmOutput> algorithmOutputs = new ArrayList<>();
		int outputNum = packOutDetail(outputSql,algorithmId,algorithmOutputs);

		String paramSql = "select * from algorithm_param where algorithm_id=?";
		final List<AlgorithmParam> algorithmParams = new ArrayList<>();
		int paramNum = packParamDetail(paramSql,algorithmId,algorithmParams);

	  final Map<String,Category> categoryMap = this.categoryDetail(algorithmId);
		String sql4 = "select * from algorithm where id=?";
		algorithmDetail = (AlgorithmDetail) Query.executeQueryObject(sql4, new Object[] { algorithmId },
				new QueryCallBack() {
					@Override
					public Object doExecute(ResultSet rs) {
						AlgorithmDetail a = null;
						try {
							while (rs.next()) {
								a = new AlgorithmDetail(rs.getInt("id"), rs.getString("name"),
										rs.getString("introduction"), rs.getInt("input_count"),
										rs.getInt("output_count"), rs.getInt("params_count"), rs.getString("version"),
										categoryMap.get("function"), rs.getString("location_uri"),
										rs.getString("company_name"), rs.getString("postfix"), rs.getString("platform"),
										rs.getBoolean("is_contain_gpu"), rs.getBoolean("is_use_mpi"),
										rs.getFloat("min_cpu_idle"), rs.getFloat("min_ram_remaining"), algorithmInputs,
										algorithmOutputs, algorithmParams, rs.getBoolean("is_delete"));
								a.setType(categoryMap.get("type"));
								a.setType(null);
								a.setGenetic(rs.getBoolean("is_genetic"));
								a.setUserId(rs.getString("user_id"));
                         //       a.setCpuNum(rs.getString("cpu_num"));
								a.setCpuNum(String.valueOf(rs.getInt("cpu_num")));
							}
							//   System.out.println("cpu_num::"+a.getCpuNum());
						} catch (SQLException e) {
							e.printStackTrace();
						}
						return a;
					}
				});
		return algorithmDetail;
	}

	/**
	 *
	 * @param algorithmId
	 * @return
	 */
	private Map<String,Category> categoryDetail(String algorithmId){
		try {
			String functionSql = "select * from `algorithm`,`category` where  `algorithm`.function=category.categoryId and `algorithm`.id=?";
			List<Object> functionList = new CategoryDao().categoryDetail(functionSql,new Object[]{algorithmId});
			Category function = null;
			if(functionList.size()>0){
                function = (Category) functionList.get(0);
            }
			String typeSql = "select * from `algorithm`,`category` where  `algorithm`.type=category.categoryId and `algorithm`.id=?";
			List<Object> typeResult = new CategoryDao().categoryDetail(typeSql,new Object[]{algorithmId});
			Category type = (Category) typeResult.get(0);
			Map<String,Category> category = new HashMap<>();
			category.put("function",function);
			category.put("type",type);
			return category;
		} catch (IndexOutOfBoundsException e) {
			e.printStackTrace();
			return null;
		}
	}

	private int packInputDetail(String sql,String algorithmId,final List<AlgorithmInput> algorithmInputs){
		return (int) Query.executeQueryObject(sql, new Object[] { algorithmId }, new QueryCallBack() {
			@Override
			public Object doExecute(ResultSet rs) {
				try {
					while (rs.next())
						algorithmInputs.add(
								new AlgorithmInput(rs.getString("input_name"),
										rs.getString("type"),
										rs.getString("input_introduction"),
										rs.getBoolean("name_is_default"),
										rs.getString("suffix")));
				} catch (SQLException e) {
					e.printStackTrace();
				}
				return algorithmInputs.size();
			}
		});
	}
	private int packOutDetail(String sql,String algorithmId,final List<AlgorithmOutput> algorithmOutputs){
		return (int) Query.executeQueryObject(sql, new Object[] { algorithmId }, new QueryCallBack() {
			@Override
			public Object doExecute(ResultSet rs) {
				try {
					while (rs.next())
						algorithmOutputs.add(
								new AlgorithmOutput(rs.getString("output_name"),
										rs.getString("type"),
										rs.getString("output_introduction"),
										rs.getBoolean("name_is_default"),
										rs.getString("suffix")));
				} catch (SQLException e) {
					e.printStackTrace();
				}

				return algorithmOutputs.size();
			}
		});
	}
	private int packParamDetail(String sql,String algorithmId,final List<AlgorithmParam> algorithmParams){
		return (int) Query.executeQueryObject(sql, new Object[] { algorithmId }, new QueryCallBack() {
			@Override
			public Object doExecute(ResultSet rs) {
				try {
					while (rs.next()){
						AlgorithmParam param = new AlgorithmParam(rs.getInt("param_id"),
								rs.getString("param_symbol"),
								rs.getString("param_type"), rs.getString("param_introduction"),
								rs.getBoolean("name_is_default"));
						param.setParamDefaultValue(rs.getString("param_default_value"));
						algorithmParams.add(param);
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
				return algorithmParams.size();
			}
		});
	}
	/**
	 * By朱萌钢 获取指定算法细节
	 */
	public AlgorithmDetail getAlgorithmDetail(String algorithmId, String userId) {
		AlgorithmDetail algorithmDetail = new AlgorithmDetail();

		String inputSql = "select * from algorithm_input where algorithm_id=?";
		final List<AlgorithmInput> algorithmInputs = new ArrayList<>();
		int inputNum = packInputDetail(inputSql,algorithmId,algorithmInputs);

		String outputSql = "select * from algorithm_output where algorithm_id=?";
		final List<AlgorithmOutput> algorithmOutputs = new ArrayList<>();
		int outputNum = packOutDetail(outputSql,algorithmId,algorithmOutputs);

		String paramSql = "select * from algorithm_param where algorithm_id=?";
		final List<AlgorithmParam> algorithmParams = new ArrayList<>();
		int paramNum = packParamDetail(paramSql,algorithmId,algorithmParams);

		final Map<String,Category> categoryMap = this.categoryDetail(algorithmId);
		String sql4 = "select * from algorithm where id=?";
		algorithmDetail = (AlgorithmDetail) Query.executeQueryObject(sql4, new Object[] { algorithmId},
				new QueryCallBack() {
					@Override
					public Object doExecute(ResultSet rs) {
						AlgorithmDetail a = null;
						try {
							while (rs.next()) {
								a = new AlgorithmDetail(rs.getInt("id"), rs.getString("name"),
										rs.getString("introduction"), rs.getInt("input_count"),
										rs.getInt("output_count"), rs.getInt("params_count"), rs.getString("version"),
										categoryMap.get("function"), rs.getString("location_uri"),
										rs.getString("company_name"), rs.getString("postfix"), rs.getString("platform"),
										rs.getBoolean("is_contain_gpu"), rs.getBoolean("is_use_mpi"),
										rs.getFloat("min_cpu_idle"), rs.getFloat("min_ram_remaining"), algorithmInputs,
										algorithmOutputs, algorithmParams, rs.getBoolean("is_delete"));
								a.setType(categoryMap.get("type"));
								a.setUserId(rs.getString("user_id"));
								if(companyDao==null)
									Log4jInit.logger.info("----------------------------------------------------------------");
								a.setCompanyJson((JSONObject) companyDao.showOneCompany(rs.getString("company_name")).get(0));
								a.setGenetic(rs.getBoolean("is_genetic"));
							//	a.setCpuNum(rs.getString("cpu_num"));
								a.setCpuNum(String.valueOf(rs.getInt("cpu_num")));
							}
							 //  System.out.println("cpu_num::"+a.getCpuNum());
						} catch (SQLException e) {
							e.printStackTrace();
						}finally{
//						    DBDruidManager.closeConnection();
						}
						if (a.isDelete())
							a = null;
						return a;
					}
				});
		return algorithmDetail;
	}

	public List<Object> insertAlgorithm(AlgorithmDetail algorithm) {
		Object[] params = new Object[] { algorithm.getName(), algorithm.getIntroduction(), algorithm.getInputCount(),
				algorithm.getOutputCount(), algorithm.getParamsCount(), algorithm.getVersion(), algorithm.getFunctionId(),
				algorithm.getLocationUri(), algorithm.getCompanyName(), algorithm.getPostfix(), algorithm.getPlatform(),
				algorithm.isContainGpu(), algorithm.isUseMpi(), algorithm.getCpuNum(), algorithm.isGenetic(),
				algorithm.getMinCpuIdle(), algorithm.getMinRamRemaining(), algorithm.getUserId(), algorithm.getTypeId() };
		String sql = "insert into `algorithm` ( name, introduction, input_count, output_count,params_count,version,"
				+ "function,location_uri,company_name,postfix,platform,is_contain_gpu,is_use_mpi,cpu_num,is_genetic, min_cpu_idle,"
				+ "min_ram_remaining,user_id,type) " + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
		List<Object> results = new ArrayList<>();
		results = PublicDao.generateKeys(results,sql,params);
		if (results.size() > 0){
			return results;
		} else{
			return null;
		}
	}

	public Boolean insertAlgorithmInput(ArrayList<AlgorithmInput> insertInput) {

		Boolean isSuccess = false;

		String sql = "insert into `algorithm_input` values (null,?,?,?,?,?,?)";
		ArrayList<Object[]> insert = new ArrayList<>();
		for (AlgorithmInput input : insertInput) {
			Object[] i = new Object[6];
			i[0] = (String.valueOf(input.getId()));
			i[1] = (input.getInputName());
			i[2] = (input.getInputIntroduction());
			i[3] = input.getType();
			i[4] = input.getNameDefault();
			i[5] = input.getSuffix();
			insert.add(i);
		}
		int line = Query.executeBatchDML(sql, insert);

		if (line == insertInput.size())
			isSuccess = true;

		return isSuccess;
	}

	public Boolean updateAlgorithmInput(List<AlgorithmInput> insertInput, String algorithmId) {

		String sqlDelete = "delete from algorithm_input where algorithm_id='" + algorithmId + "'";
		int deleteResult = Query.executeDML(sqlDelete, null);
		ArrayList<AlgorithmInput> inn = new ArrayList<>();
		for (AlgorithmInput in : insertInput) {
			in.setId(Integer.valueOf(algorithmId));
			inn.add(in);
		}
		boolean result = this.insertAlgorithmInput((ArrayList<AlgorithmInput>) inn);
//		System.out.println("update algorithm input:"+result);
		return result;
	}

	public Boolean insertAlgorithmOutput(ArrayList<AlgorithmOutput> insertOutput) {

		Boolean isSuccess = false;
		String sql = "insert into `algorithm_output` values (null,?,?,?,?,?,?)";
		ArrayList<Object[]> insert = new ArrayList<>();
		for (AlgorithmOutput output : insertOutput) {
			Object[] o = new Object[6];
			o[0] = String.valueOf(output.getId());
			o[1] = output.getOutputName();
			o[2] = output.getOutputIntroduction();
			o[3] = output.getType();
			o[4] = output.getNameDefault();
			o[5] = output.getSuffix();
			insert.add(o);
		}
		int line = Query.executeBatchDML(sql, insert);

		if (line == insertOutput.size())
			isSuccess = true;

		return isSuccess;
	}

	public Boolean updateAlgorithmOutput(List<AlgorithmOutput> insertOutput, String algorithmId) {

		String sqlDelete = "delete from algorithm_output where algorithm_id='" + algorithmId + "'";
		int deleteResult = Query.executeDML(sqlDelete, null);
		ArrayList<AlgorithmOutput> ouu = new ArrayList<>();
		for (AlgorithmOutput in : insertOutput) {
			in.setId(Integer.valueOf(algorithmId));
			ouu.add(in);
		}
		boolean result = this.insertAlgorithmOutput((ArrayList<AlgorithmOutput>) ouu);
		return result;
	}


	public Boolean insertAlgorithmParam(ArrayList<AlgorithmParam> insertParam) {

		Boolean isSuccess = false;

		String sql = "insert into `algorithm_param`(algorithm_id,param_symbol,param_type,"
				+ "param_default_value, param_introduction,name_is_default) values(?,?,?,?,?,?)";
		ArrayList<Object[]> insert = new ArrayList<>();
		for (AlgorithmParam param : insertParam) {
			Object[] p = new Object[6];
			p[0] = String.valueOf(param.getId());
			p[1] = param.getParamSymbol();
			p[2] = param.getParamType();
			p[3] = param.getParamDefaultValue();
			p[4] = param.getParamIntroduction();
			p[5] = param.getNameDefault();
			insert.add(p);
		}
		int line = Query.executeBatchDML(sql, insert);
		if (line == insertParam.size())
			isSuccess = true;

		return isSuccess;
	}

	public Boolean updateAlgorithmParam(List<AlgorithmParam> insertParam, String algorithmId) {

		String sqlDelete = "delete from algorithm_param where algorithm_id='" + algorithmId + "'";
		int deleteResult = Query.executeDML(sqlDelete, null);
		ArrayList<AlgorithmParam> inn = new ArrayList<>();
		for (AlgorithmParam in : insertParam) {
			in.setId(Integer.valueOf(algorithmId));
			inn.add(in);
		}
		boolean result= this.insertAlgorithmParam((ArrayList<AlgorithmParam>) inn);
		return result;
	}

	public int getNextAlgorithmId() {
		String sql = "select max(id) from algorithm ";
		int result = (int) Query.executeQueryObject(sql, null, new QueryCallBack() {
			@Override
			public Object doExecute(ResultSet rs) {
				int result = 0;
				try {
					while (rs.next()) {
						result = rs.getInt(1);
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}finally{
//               	 DBDruidManager.closeConnection();
               }
				return result;
			}
		});
		return result + 1;
	}

	public HttpResult insertAlgorithmDetail(AlgorithmDetail algorithm, List<AlgorithmInput> inputsList,
			List<AlgorithmOutput> outputsList, List<AlgorithmParam> paramsList) {

		boolean isSuccess = false;
		int id = -1;
		List<Object> result = this.insertAlgorithm(algorithm);
		if (result.size() > 0) {
			id = (int) result.get(0);
			isSuccess = true;
		}
		ArrayList<AlgorithmInput> in = new ArrayList<>();
		for (AlgorithmInput i : inputsList) {
			i.setId(id);
			in.add(i);
		}
		ArrayList<AlgorithmOutput> out = new ArrayList<>();
		for (AlgorithmOutput o : outputsList) {
			o.setId(id);
			out.add(o);
		}
		ArrayList<AlgorithmParam> param = new ArrayList<>();
		for (AlgorithmParam p : paramsList) {
			p.setId(id);
			param.add(p);
		}
		HttpResult httpResult = new HttpResult();
		httpResult.setResult(isSuccess && this.insertAlgorithmInput(in) && this.insertAlgorithmOutput(out)
				&& this.insertAlgorithmParam(param));
		httpResult.setMessage(id+"");
		return httpResult;
	}
	// 得到文件的路径
	public String getUrl(String algorithmId) {
		AlgorithmDetail algorithmDetail = this.getAlgorithmDetail(algorithmId, null);
		String url = algorithmDetail.getLocationUri();
		return url;
	}

	/**
	 * By zhuyaokun
	 * 
	 * @param algorithmId
	 * @return
	 */
	public boolean deleteAlgorithmById(String algorithmId) {
		String sql = "update algorithm set is_delete = 1 where id = ?";
		int result = Query.executeDML(sql, new Object[] { algorithmId });
		return result > 0 ? true : false;
	}

	public boolean updataAlgorithmById(String userId, String algorithmId, AlgorithmDetail algorithm,
			List<AlgorithmInput> inputsList, List<AlgorithmOutput> outputsList, List<AlgorithmParam> paramsList) {
		String sql = "update algorithm set name = ?, location_uri = ?, introduction = ?,input_count = ?,output_count = ?,params_count = ?,"
				+ "version = ?,function = ?,type = ?,user_id = ?,company_name = ?,postfix = ?,platform = ?,"
				+ "is_contain_gpu = ?,is_use_mpi = ?,cpu_num = ? , min_cpu_idle = ?,min_ram_remaining = ?,is_genetic=?" +
                " where id =?";
		Object[] params = new Object[] { algorithm.getName(), algorithm.getLocationUri(), algorithm.getIntroduction(), algorithm.getInputCount(),
				algorithm.getOutputCount(), algorithm.getParamsCount(), algorithm.getVersion(), algorithm.getFunctionId(),
				algorithm.getTypeId(), userId, algorithm.getCompanyName(), algorithm.getPostfix(),
				algorithm.getPlatform(), algorithm.isContainGpu(), algorithm.isUseMpi(), algorithm.getCpuNum(),
                algorithm.getMinCpuIdle(),algorithm.getMinRamRemaining(),algorithm.isGenetic(), algorithmId };
		int rr = Query.executeDML(sql, params);
		boolean algorithmResult = rr > 0 ? true : false;
		algorithmResult = algorithmResult && this.updateAlgorithmInput(inputsList, algorithmId)
				&& this.updateAlgorithmOutput(outputsList, algorithmId)
				&& this.updateAlgorithmParam(paramsList, algorithmId);
		return algorithmResult;
	}

	public List<Object> allAlgorithmInCategory(){
		String sql = "select * from `algorithm` where id in (select * from " +
				"((select `algorithm`.id from `algorithm`,`category` where  " +
				"`algorithm`.type=category.categoryId and `algorithm`.is_delete=0) " +
				"union (select `algorithm`.id from `algorithm`,`category` where  " +
				"`algorithm`.function=category.categoryId and `algorithm`.is_delete=0)) " +
				"as a) ORDER BY id desc";
		return algorithmDetail(sql);
	}
	public List<Object> algorithmDetail(String sql){
		final List<Object> results = new ArrayList<>();
		return Query.executeQueryList(results, sql,null, new QueryCallBackList() {
			@Override
			public List<Object> doExecuteList(ResultSet rs, List<Object> results) {
				try {
					while (rs.next()) {
						final Map<String,Category> categoryMap = new AlgorithmDao().categoryDetail(rs.getInt("id")+"");
						if (categoryMap!=null) {
                            {
                                AlgorithmDetail a = new AlgorithmDetail();
                                a = packAlgorithm(a,rs,categoryMap);
                                if (!rs.getBoolean("is_delete"))
                                    results.add(a);
                            }
						}
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}finally{
//               	 DBDruidManager.closeConnection();
               }
				return results;
			}
		});
	}
	public List<Object> getAllAlgorithms() {
		String sql = "select * from algorithm where is_delete = 0 order by id desc";
        return algorithmDetail(sql);
	}
	
	/**
	 * By zhuyaokun get algorithm infor by id , careless is delete
	 * @param algorithmId
	 * @return
	 */
	public AlgorithmDetail getAlgorithmDetailById(String algorithmId) {
		String sql = "select * from algorithm where id = ?";
		return (AlgorithmDetail) Query.executeQueryObject(sql,new Object[]{algorithmId}, new QueryCallBack() {
            @Override
            public Object doExecute(ResultSet rs) {
				AlgorithmDetail a = new AlgorithmDetail();
                try {
                    while (rs.next()) {
						final Map<String,Category> categoryMap = new AlgorithmDao().categoryDetail(rs.getInt("id")+"");
						a = packAlgorithm(a,rs,categoryMap);
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }finally{
//               	 DBDruidManager.closeConnection();
               }
                return a;
            }
        });
	}
	public boolean insertHistoryAlgorithm(String taskHash, String blockId, String state, String algorithmId, int size) {
		String sql = "insert into `history_algorithm` (task_hash,algorithm_hash,start_info,start_time,algorithm_id,job_num) values (?,?,?,now(),?,?)";
		return Query.executeDML(sql, new Object[]{taskHash,blockId,state,algorithmId,size})>0;
	}
	public boolean updateRunningHistoryAlgorithmState(String state, String taskHash, String blockId) {
		String sql = "update `history_algorithm` set state=? where task_hash=? and algorithm_hash=?";
		return Query.executeDML(sql, new Object[]{state,taskHash,blockId})>0;
	}
	public boolean endRunningHistoryAlgorithmState(String taskHash, String blockId) {
		String sql = "update `history_algorithm` set end_time=now() where task_hash=? and algorithm_hash=?";
		return Query.executeDML(sql, new Object[]{taskHash,blockId})>0;
	}

	public static void main(String[] args) {
		JSONObject result = JSONObject.fromObject(new AlgorithmDao().getAlgorithmDetailWithoutUserId("378"));
		result.put("blockId","test block id");
		Log4jInit.logger.info(result.toString());
	}

	/**
	 * 针对子任务中的单个算法的状态更新方法，状态包括：完成、恢复、暂停、终止，对应的state值为1、2、3、4
	 * 同时保证将其对应的作业的状态进行更新，包括表history_algorithm、history_job、socket_log表，其中，后者是以作业为展示单位的作业状态展示
	 * @param runningJobIds
	 * @param subTaskHash
	 * @param algorithmHash
	 * @return
	 */
	public boolean algorithmFinishedStopPauseStateUpdate(int state,List<String> runningJobIds, String subTaskHash, String algorithmHash) {
		JobDao jobDao = new JobDao();
		SocketLogDao socketLogDao = new SocketLogDao();
		boolean result = true;
		switch (state){
			case 1:
				for(String jobId:runningJobIds)
				{
					//history_job表
					result = result&&jobDao.updateJobState("DONE",subTaskHash,algorithmHash,jobId);
					//socket_Log表
					result = result&&socketLogDao.updateAlgorithmStateByJobId("1",jobId);
				}
				//history_algorithm表
				result = result&&this.endRunningHistoryAlgorithmState(subTaskHash,algorithmHash);
				break;
			case 2:
				for(String jobId:runningJobIds)
				{
					//history_job表
					result = result&&jobDao.updateJobState("RUNNING",subTaskHash,algorithmHash,jobId);
					//socket_Log表
					result = result&&socketLogDao.updateAlgorithmStateByJobId("2",jobId);
				}
				break;
			case 3:
				for(String jobId:runningJobIds)
				{
					//history_job表
					result = result&&jobDao.updateJobState("PAUSE",subTaskHash,algorithmHash,jobId);
					//socket_Log表
					result = result&&socketLogDao.updateAlgorithmStateByJobId("3",jobId);
				}
				break;
			case 4:
				for(String jobId:runningJobIds)
				{
					//history_job表
					result = result&&jobDao.updateJobState("STOP",subTaskHash,algorithmHash,jobId);
					//socket_Log表
					result = result&&socketLogDao.updateAlgorithmStateByJobId("5",jobId);
				}
				//history_algorithm表
				result = result&&this.endRunningHistoryAlgorithmState(subTaskHash,algorithmHash);
				break;
			default:
				return false;
		}
		return result;
	}
	
	/**
	 * 获取算法版本相关信息
	 * @param algorithmId
	 * @return
	 */
	public JSONObject getVersionInfoById(String algorithmId){
		String sql = "select version,ftp_uri,ftp_version from algorithm where id = ?";
		return (JSONObject)Query.executeQueryObject(sql, new Object[]{algorithmId}, new QueryCallBack() {
			@Override
			public Object doExecute(ResultSet rs) {
				JSONObject result = new JSONObject();
				try {
					while(rs.next()) {
						result.put("version", rs.getString("version"));
						result.put("ftp_uri", rs.getString("ftp_uri"));
						result.put("ftp_version", rs.getString("ftp_version"));
					}
				} catch (SQLException e) {
					e.printStackTrace();
				}
				return result;
			}
		});
	}
	/**
	 * 更新算法版本相关信息
	 * @param algorithmId
	 * @return
	 */
	public boolean updateVersionInfoById(String algorithmId, String ftpUri, String ftpVersion){
		String sql = "UPDATE `algorithm` SET ftp_uri=?,ftp_version=? where id = ?";
		Object[] params = new Object[]{ftpUri, ftpVersion, algorithmId};
		//返回结果
		List<Object> results = new ArrayList<>();
		int resultNum = Query.executeDML(sql, params);
		boolean result = (resultNum == -1)?false:true;
		return result;
	}
}
